#ifndef	__BFX_REF_XMLELEMENT_H__
#define	__BFX_REF_XMLELEMENT_H__

namespace BFX
{

//////////////////////////////////////////////////////////////////////////////

#ifdef	BFX_DLL_BUILD
template class BFX_API REF<REFXMLAttributeMap>;
#endif	//	__USRDLL

//////////////////////////////////////////////////////////////////////////////

// Represents an element.
class BFX_API REFXMLElement : public REFXMLLinkedNode
{
	friend class REFXMLAttributeMap;
	friend class REFXMLDocument;

protected:
	REFXMLElement(REFXMLName* pName, REFXMLDocument* pDoc);

public:
	virtual ~REFXMLElement();

	// Gets the name of the node.
	virtual UniString GetName() const;
	// Gets the name of the current node without the namespace prefix.
	virtual UniString GetLocalName() const;

	// Gets the namespace URI of this node.
	virtual UniString NamespaceURI() const;

	// Gets or sets the namespace prefix of this node.
	virtual UniString GetPrefix() const;
	virtual void SetPrefix(const UniString& str);

	// Gets the type of the current node.
	virtual XMLNodeType GetNodeType() const;

	virtual REFXMLNode* GetParentNode() const;
	
	// Gets the XmlDocument that contains this node.
	virtual REFXMLDocument* GetOwnerDocument() const;

	virtual REFXMLAttributeMap* GetAttributes() const;

	// Gets or sets the concatenated values of the node and all its children.
	virtual UniString GetInnerText() const;
	virtual void SetInnerText(const UniString& str);

	// Gets or sets the markup representing just the children of this node.
	virtual UniString GetInnerXml() const;
	virtual void SetInnerXml(const UniString& str);

	virtual REFXMLNode* GetNextSibling() const;

	// Saves the current node to the specified XmlWriter.
	virtual void WriteTo(REFXMLWriter* w) const;
	// Saves all the children of the node to the specified XmlWriter.
	virtual  void WriteContentTo(REFXMLWriter* w) const;

	virtual void RemoveAll();

	// Removes all attributes from the element.
	void RemoveAllAttributes();
	// Gets a value indicating whether the current node has any attributes.
	bool HasAttributes() const;
	// Returns the value for the attribute with the specified name.
	UniString GetAttribute(const UniString& strName) const;
	// Sets the value of the attribute with the specified name.
	void SetAttribute(const UniString& strName, const UniString& strValue);
	// Removes an attribute by name.
	void RemoveAttribute(const UniString& strName);
	// Returns the XmlAttribute with the specified name.
	REFXMLAttribute* GetAttributeNode(const UniString& strName) const;
	// Adds the specified XmlAttribute.
	REFXMLAttribute* SetAttributeNode(REFXMLAttribute* pNewAttr);
	// Removes the specified XmlAttribute.
	REFXMLAttribute* RemoveAttributeNode(REFXMLAttribute* pOldAttr);

	// Returns a XmlNodeList containing
	// a list of all descendant elements that match the specified name.
	REFXMLNodeList* GetElementsByTagName(const UniString& strName) const;

	// Gets or sets whether the element does not have any children.
	bool IsEmpty() const;
	void SetEmpty();

	//
	// DOM Level 2
	//
	// Returns the value for the attribute with the specified LocalName and NamespaceURI.
	UniString GetAttribute(const UniString& strLocalName, const UniString& strNamespaceURI) const;
	// Sets the value of the attribute with the specified name and namespace.
	UniString SetAttribute(const UniString& strLocalName, const UniString& strNamespaceURI, const UniString& strValue);
	// Removes an attribute specified by LocalName and NamespaceURI.
	void RemoveAttribute(const UniString& strLocalName, const UniString& strNamespaceURI);

	// Returns the XmlAttribute with the specified LocalName and NamespaceURI.
	REFXMLAttribute* GetAttributeNode(const UniString& strLocalName, const UniString& strNamespaceURI) const;
	// Adds the specified XmlAttribute.
	REFXMLAttribute* SetAttributeNode(const UniString& strLocalName, const UniString& strNamespaceURI);
	// Removes the XmlAttribute specified by LocalName and NamespaceURI.
	REFXMLAttribute* RemoveAttributeNode(const UniString& strLocalName, const UniString& strNamespaceURI);

	// Returns a XmlNodeList containing 
	// a list of all descendant elements that match the specified name.
	REFXMLNodeList* GetElementsByTagName(const UniString& strLocalName, const UniString& strNamespaceURI) const;

protected:
	virtual bool IsContainer() const;

	virtual REFXMLLinkedNode* GetFirstNode() const;
	virtual void SetFirstNode(REFXMLLinkedNode* pNode);

	virtual REFXMLLinkedNode* GetLastNode() const;
	virtual void SetLastNode(REFXMLLinkedNode* pNode);

	virtual void SetParent(REFXMLNode* pNode);

	virtual bool IsValidChildType(XMLNodeType type) const;

	//the function is provided only at Load time to speed up Load process
	virtual REFXMLNode* AppendChildForLoad(REFXMLNode* pNewChild, REFXMLDocument* pDoc);

	REFXMLName* GetXmlName() const;
	void SetXmlName(REFXMLName* pName);

private:
	REF<REFXMLLinkedNode>	m_pFirstChild;
	REFXMLLinkedNode*	m_pLastChild;
	REFXMLName*		m_pName;
	REF<REFXMLAttributeMap>	m_pAttributes;
};

}	//	namespace BFX

#endif	//	__BFX_REF_XMLELEMENT_H__
